home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / builtins / declare.def < prev    next >
Text File  |  1994-05-31  |  7KB  |  281 lines

  1. This file is declare.def, from which is created declare.c.
  2. It implements the builtins "declare" and "local" in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES declare.c
  23.  
  24. $BUILTIN declare
  25. $FUNCTION declare_builtin
  26. $SHORT_DOC declare [-[frxi]] name[=value] ...
  27. Declare variables and/or give them attributes.  If no NAMEs are
  28. given, then display the values of variables instead.
  29.  
  30. The flags are:
  31.  
  32.   -f    to select from among function names only,
  33.   -r    to make NAMEs readonly,
  34.   -x    to make NAMEs export,
  35.   -i    to make NAMEs have the `integer' attribute set.
  36.  
  37. Variables with the integer attribute have arithmetic evaluation (see
  38. `let') done when the variable is assigned to.
  39.  
  40. Using `+' instead of `-' turns off the given attribute instead.  When
  41. used in a function, makes NAMEs local, as with the `local' command.
  42. $END
  43.  
  44. $BUILTIN typeset
  45. $FUNCTION declare_builtin
  46. $SHORT_DOC typeset [-[frxi]] name[=value] ...
  47. Obsolete.  See `declare'.
  48. $END
  49.  
  50. #include <stdio.h>
  51.  
  52. #if defined (HAVE_STRING_H)
  53. #  include <string.h>
  54. #else /* !HAVE_STRING_H */
  55. #  include <strings.h>
  56. #endif /* !HAVE_STRING_H */
  57.  
  58. #include "../shell.h"
  59.  
  60. extern int variable_context, array_needs_making;
  61.  
  62. static int declare_internal ();
  63.  
  64. /* Declare or change variable attributes. */
  65. int
  66. declare_builtin (list)
  67.      register WORD_LIST *list;
  68. {
  69.   return (declare_internal (list, 0));
  70. }
  71.  
  72. $BUILTIN local
  73. $FUNCTION local_builtin
  74. $SHORT_DOC local name[=value] ...
  75. Create a local variable called NAME, and give it VALUE.  LOCAL
  76. can only be used within a function; it makes the variable NAME
  77. have a visible scope restricted to that function and its children.
  78. $END
  79. int
  80. local_builtin (list)
  81.      register WORD_LIST *list;
  82. {
  83.   if (variable_context)
  84.     return (declare_internal (list, 1));
  85.   else
  86.     {
  87.       builtin_error ("Can only be used in a function");
  88.       return (EXECUTION_FAILURE);
  89.     }
  90. }
  91.  
  92. /* The workhorse function. */
  93. static int
  94. declare_internal (list, local_var)
  95.      register WORD_LIST *list;
  96.      int local_var;
  97. {
  98.   int flags_on = 0, flags_off = 0;
  99.   int any_failed = 0;
  100.  
  101.   while (list)
  102.     {
  103.       register char *t = list->word->word;
  104.       int *flags;
  105.  
  106.       if (t[0] == '-' && t[1] == '-' && t[2] == '\0')
  107.     {
  108.       list = list->next;
  109.       break;
  110.     }
  111.  
  112.       if (*t != '+' && *t != '-')
  113.     break;
  114.  
  115.       if (*t == '+')
  116.     flags = &flags_off;
  117.       else
  118.     flags = &flags_on;
  119.  
  120.       t++;
  121.  
  122.       while (*t)
  123.     {
  124.       if (*t == 'f')
  125.         *flags |= att_function, t++;
  126.       else if (*t == 'x')
  127.         *flags |= att_exported, t++, array_needs_making = 1;
  128.       else if (*t == 'r')
  129.         *flags |= att_readonly, t++;
  130.       else if (*t == 'i')
  131.         *flags |= att_integer, t++;
  132.       else
  133.         {
  134.           builtin_error ("unknown option: `-%c'", *t);
  135.           return (EX_USAGE);
  136.         }
  137.     }
  138.  
  139.       list = list->next;
  140.     }
  141.  
  142.   /* If there are no more arguments left, then we just want to show
  143.      some variables. */
  144.   if (!list)
  145.     {
  146.       /* Show local variables defined at this context level if this is
  147.      the `local' builtin. */
  148.       if (local_var)
  149.     {
  150.       register SHELL_VAR **vlist;
  151.       register int i;
  152.  
  153.       vlist = map_over (variable_in_context, shell_variables);
  154.  
  155.       if (vlist)
  156.         {
  157.           for (i = 0; vlist[i]; i++)
  158.         print_assignment (vlist[i]);
  159.  
  160.           free (vlist);
  161.         }
  162.     }
  163.       else
  164.     {
  165.       if (!flags_on)
  166.         set_builtin ((WORD_LIST *)NULL);
  167.       else
  168.         set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
  169.     }
  170.  
  171.       fflush (stdout);
  172.       return (EXECUTION_SUCCESS);
  173.     }
  174.  
  175. #define NEXT_VARIABLE() free (name); list = list->next; continue
  176.  
  177.   /* There are arguments left, so we are making variables. */
  178.   while (list)
  179.     {
  180.       char *value, *name = savestring (list->word->word);
  181.       int offset = assignment (name);
  182.  
  183.       if (offset)
  184.     {
  185.       name[offset] = '\0';
  186.       value = name + offset + 1;
  187.     }
  188.       else
  189.     value = "";
  190.  
  191.       if (legal_identifier (name) == 0)
  192.     {
  193.       builtin_error ("%s: not a legal variable name", name);
  194.       any_failed++;
  195.       NEXT_VARIABLE ();
  196.     }
  197.  
  198.       /* If VARIABLE_CONTEXT has a non-zero value, then we are executing
  199.      inside of a function.  This means we should make local variables,
  200.      not global ones. */
  201.  
  202.       if (variable_context)
  203.     make_local_variable (name);
  204.  
  205.       /* If we are declaring a function, then complain about it in some way.
  206.      We don't let people make functions by saying `typeset -f foo=bar'. */
  207.  
  208.       /* There should be a way, however, to let people look at a particular
  209.      function definition by saying `typeset -f foo'. */
  210.  
  211.       if (flags_on & att_function)
  212.     {
  213.       if (offset)
  214.         {
  215.           builtin_error ("Can't use `-f' to make functions");
  216.           return (EXECUTION_FAILURE);
  217.         }
  218.       else
  219.         {
  220.           SHELL_VAR *find_function (), *funvar;
  221.           funvar = find_function (name);
  222.  
  223.           if (funvar)
  224.         {
  225.           char *result = named_function_string
  226.             (name, (COMMAND *)function_cell (funvar), 1);
  227.           printf ("%s\n", result);
  228.         }
  229.           else
  230.         any_failed++;
  231.           NEXT_VARIABLE ();
  232.         }
  233.     }
  234.       else
  235.     {
  236.       SHELL_VAR *var;
  237.  
  238.       var = find_variable (name);
  239.  
  240.       if (!var)
  241.         var = bind_variable (name, "");
  242.  
  243.       /* We are not allowed to rebind readonly variables that
  244.          already are readonly unless we are turning off the
  245.          readonly bit. */
  246.       if (flags_off & att_readonly)
  247.         flags_on &= ~att_readonly;
  248.  
  249.       if (value && readonly_p (var) && (!(flags_off & att_readonly)))
  250.         {
  251.           builtin_error ("%s: readonly variable", name);
  252.           any_failed++;
  253.           NEXT_VARIABLE ();
  254.         }
  255.  
  256.       var->attributes |= flags_on;
  257.       var->attributes &= ~flags_off;
  258.  
  259.       if (offset)
  260.         {
  261.           free (var->value);
  262.           if (integer_p (var))
  263.         {
  264.           long val, evalexp ();
  265.           char *itos ();
  266.  
  267.           val = evalexp (value);
  268.           var->value = itos ((int)val);
  269.         }
  270.           else
  271.         var->value = savestring (value);
  272.         }
  273.     }
  274.  
  275.       stupidly_hack_special_variables (name);
  276.  
  277.       NEXT_VARIABLE ();
  278.     }
  279.   return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
  280. }
  281.